package cn.sfrog.project.biz.admin.websocket;

import cn.hutool.core.bean.BeanUtil;
import cn.sfrog.common.utils.DateUtils;
import cn.sfrog.common.utils.StringUtils;
import cn.sfrog.project.biz.admin.domain.BizMessageConversation;
import cn.sfrog.project.biz.admin.domain.BizMessageLog;
import cn.sfrog.project.biz.admin.enums.MessageTypeEnum;
import cn.sfrog.project.biz.admin.mapper.BizLiveRoomMapper;
import cn.sfrog.project.biz.admin.mapper.BizMessageConversationMapper;
import cn.sfrog.project.biz.admin.mapper.BizMessageLogMapper;
import cn.sfrog.project.biz.admin.utils.bean.BeanContext;
import cn.sfrog.project.biz.web.vo.websocket.AppSocketMessageVO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@ServerEndpoint("/api/messageServer/{userId}")
@Component
public class MessageSocketServer {

    //存放用户的容器
    public static ConcurrentHashMap<Long, MessageSocketServer> platContainer = new ConcurrentHashMap<>();

    @Autowired
    private BizMessageLogMapper messageLogMapper;
//    private final BizMessageLogMapper messageLogMapper = BeanContext.getBean(BizMessageLogMapper.class);

    @Autowired
    private BizMessageConversationMapper messageConversationMapper;
//    private final BizMessageConversationMapper messageConversationMapper = BeanContext.getBean(BizMessageConversationMapper.class);

//    private final BizLiveRoomMapper liveRoomMapper = BeanContext.getBean(BizLiveRoomMapper.class);


    private Session session;

    private Long userId;

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        this.session = session;
        this.userId = userId;
        platContainer.remove(userId);
        platContainer.put(userId, this);
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        if (StringUtils.isBlank(message)) {
            return;
        }
        //System.out.println("收到消息:::::"+message);
        AppSocketMessageVO messageVO = JSONObject.parseObject(message, AppSocketMessageVO.class);
        if (MessageTypeEnum.CHECK_HEART.getCode().equals(messageVO.getType())) {
            session.getBasicRemote().sendText(message);
            return;
        }
        //处理会话
        BizMessageConversation bizMessageConversation = this.handleMessageConversation(userId, messageVO.getReceiveUserId());
        //新增消息
        BizMessageLog bizMessageLog = new BizMessageLog();
        BeanUtil.copyProperties(messageVO, bizMessageLog);
        bizMessageLog.setSendUserId(userId);
        bizMessageLog.setReadStatus("0");
        bizMessageLog.setCreateTime(new Date());
        bizMessageLog.setUpdateTime(new Date());
        bizMessageLog.setConversationId(bizMessageConversation.getId());
        bizMessageLog.setCreateBy(userId.toString());
        bizMessageLog.setUpdateBy(userId.toString());
        messageLogMapper.insert(bizMessageLog);
        //推送消息
        MessageSocketServer messageSocketServer = platContainer.get(messageVO.getReceiveUserId());
        if (messageSocketServer != null) {
            messageSocketServer.session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 发送直播通知群发
     *
     * @param userIds
     * @param message
     */
    public void sendGroupMessage(List<Long> userIds, String message) {
        for (Long id : userIds) {
            try {
                if (platContainer.get(id) !=null) {
                    platContainer.get(id).session.getBasicRemote().sendText(message);
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    @OnClose
    public void onClose() {
        platContainer.remove(userId);
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    /**
     * 设A 为发送方 B为接收方
     * 1.查询并新增 A->B 或B-> 的会话 没有的话 就新增
     * 2.若A->B 则 B的未读数量+1 A不变
     *
     * @param sendUserId    发送方用户主键
     * @param receiveUserId 接收方用户主键
     */
    private BizMessageConversation handleMessageConversation(Long sendUserId, Long receiveUserId) {
        LambdaQueryWrapper<BizMessageConversation> wrapper = Wrappers.lambdaQuery(BizMessageConversation.class)
                .or(e -> e.eq(BizMessageConversation::getSendUserId, sendUserId).eq(BizMessageConversation::getReceiveUserId, receiveUserId))
                .or(e -> {
                    e.eq(BizMessageConversation::getSendUserId, receiveUserId).eq(BizMessageConversation::getReceiveUserId, sendUserId);
                });
        BizMessageConversation bizMessageConversation = messageConversationMapper.selectOne(wrapper);
        if (bizMessageConversation == null) {
            bizMessageConversation = new BizMessageConversation();
            bizMessageConversation.setSendUserId(sendUserId);
            bizMessageConversation.setReceiveUserId(receiveUserId);
            bizMessageConversation.setReceiveUnreadCount(1);
            bizMessageConversation.setCreateTime(DateUtils.getNowDate());
            bizMessageConversation.setUpdateTime(DateUtils.getNowDate());
            bizMessageConversation.setCreateBy(userId.toString());
            bizMessageConversation.setUpdateBy(userId.toString());
            messageConversationMapper.insert(bizMessageConversation);
        } else {
            bizMessageConversation.setUpdateTime(new Date());
            if (receiveUserId.equals(bizMessageConversation.getReceiveUserId())) {
                bizMessageConversation.setReceiveUnreadCount(bizMessageConversation.getReceiveUnreadCount() + 1);
            } else {
                bizMessageConversation.setSendUnreadCount(bizMessageConversation.getSendUnreadCount() + 1);
            }
            bizMessageConversation.setUpdateBy(userId.toString());
            bizMessageConversation.setUpdateTime(DateUtils.getNowDate());
            messageConversationMapper.updateById(bizMessageConversation);
        }
        return bizMessageConversation;
    }
}
